import sys
import os
import cv2
import shutil
import tempfile
import threading
from deepface import DeepFace
from PyQt5.QtWidgets import (
    QApplication, QLabel, QPushButton, QVBoxLayout, QHBoxLayout,
    QWidget, QProgressBar, QFileDialog, QGridLayout, QFrame, QComboBox, QLineEdit, QStackedLayout
)
from PyQt5.QtGui import QPixmap, QFont, QImage, QMovie
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer, QObject, pyqtSlot

from psychological_report_pdf import PsychologicalPDFReport
import datetime
from qwen_compatible_client import QwenCompatibleClient
from PyQt5.QtWidgets import QDialog, QLabel, QVBoxLayout, QProgressBar, QApplication
from PyQt5.QtCore import Qt, QThread, pyqtSignal
import time

# 卡通风格字体
CARTOON_FONT = "Comic Sans MS"
EMO_MAP = {
    "高兴": "😄", "伤心": "😢", "生气": "😡", "害怕": "😨", "厌恶": "🤢", "惊讶": "😲", "平淡": "😐"
}

os.environ["TF_ENABLE_ONEDNN_OPTS"] = "0"


class DeepFaceThread(QThread):
    result_signal = pyqtSignal(dict, str)
    error_signal = pyqtSignal(str)

    def __init__(self, img_path):
        super().__init__()
        self.img_path = img_path

    def run(self):
        try:
            result = DeepFace.analyze(
                img_path=self.img_path,
                actions=['emotion'],
                enforce_detection=False,
                detector_backend='opencv',
            )
            if isinstance(result, list) and len(result) > 0:
                result = result[0]
            if isinstance(result, dict) and 'dominant_emotion' in result:
                emotion = result['dominant_emotion']
                probs = result['emotion']
                self.result_signal.emit(probs, emotion)
            else:
                self.error_signal.emit("未检测到人脸或 DeepFace 返回结果无效")
        except Exception as e:
            self.error_signal.emit(f"DeepFace 调用错误: {e}")


class SystemInitWorker(QObject):
    finished = pyqtSignal()
    progress = pyqtSignal(int, str)

    def __init__(self):
        super().__init__()

    @pyqtSlot()
    def run(self):
        # 模拟初始化步骤，并按顺序发射进度
        total_steps = 5
        try:
            self.progress.emit(15, "加载人脸识别模型")
            import deepface  # 确保deepface已能用
            _ = DeepFace.build_model("Emotion")
        except Exception as e:
            self.progress.emit(20, f"人脸模型加载异常: {e}")

        self.progress.emit(35, "初始化摄像头")
        try:
            temp_cap = cv2.VideoCapture(0)
            temp_cap.release()
        except Exception as e:
            self.progress.emit(40, f"摄像头初始化异常: {e}")

        self.progress.emit(60, "准备AI反馈引擎")
        try:
            from ai_chat_dialog import SimpleSelfLearningEngine
            _ = SimpleSelfLearningEngine()
        except Exception as e:
            self.progress.emit(65, f"AI引擎异常: {e}")

        self.progress.emit(85, "准备心理报告模块")
        try:
            _ = PsychologicalPDFReport()
        except Exception as e:
            self.progress.emit(90, f"心理模块异常: {e}")
        self.progress.emit(100, "初始化完成")
        self.finished.emit()

class PDFProgressDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("心理报告生成中")
        self.setFixedSize(480, 220)
        self.setWindowFlags(self.windowFlags() | Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint)
        self.setStyleSheet("""
            QDialog {
                background: qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 #e9f7ed, stop:1 #c8efd4);
                border-radius: 24px;
            }
            QLabel {
                color: #298d60;
                font-size: 28px;
                font-family: "Comic Sans MS", "微软雅黑";
            }
            QProgressBar {
                border: 2px solid #158a5a; border-radius: 14px; background: #e2f6e6;
                font-size: 22px;
                height: 40px;
            }
            QProgressBar::chunk {
                background-color: #26d488;
                border-radius: 12px;
            }
        """)
        layout = QVBoxLayout(self)
        layout.setAlignment(Qt.AlignCenter)
        self.label = QLabel("PDF正在生成，请稍候…")
        self.label.setAlignment(Qt.AlignCenter)
        self.progress = QProgressBar()
        self.progress.setMinimum(0)
        self.progress.setMaximum(100)
        self.progress.setValue(5)  # 起始进度
        layout.addStretch(1)
        layout.addWidget(self.label, alignment=Qt.AlignCenter)
        layout.addSpacing(18)
        layout.addWidget(self.progress, alignment=Qt.AlignCenter)
        layout.addStretch(1)

class PDFGeneratorThread(QThread):
    progress_signal = pyqtSignal(int)
    finished_signal = pyqtSignal(str, bool)  # (pdf_path, success)

    def __init__(self, pdf_generator, kwargs):
        super().__init__()
        self.pdf_generator = pdf_generator
        self.kwargs = kwargs

    def run(self):
        try:
            # 模拟进度（实际生成PDF没法实时细粒度进度，只能估算和分段更新）
            self.progress_signal.emit(10)
            time.sleep(0.2)
            self.progress_signal.emit(25)
            time.sleep(0.2)
            self.progress_signal.emit(50)
            pdf_path = self.pdf_generator.gen_report(**self.kwargs)
            self.progress_signal.emit(80)
            time.sleep(0.15)
            self.progress_signal.emit(100)
            time.sleep(0.15)
            self.finished_signal.emit(pdf_path, True)
        except Exception as e:
            self.finished_signal.emit(str(e), False)


class LoginDialog(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("欢迎登录 - AI心理成长关护系统")
        self.setFixedSize(980, 780)
        self.setStyleSheet("""
            QWidget {
                background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #e9f7ed, stop:1 #c8efd4);
            }
        """)
        self.username = ""
        self.selected_mood = "高兴"
        self.initUI()

    def initUI(self):
        card = QFrame(self)
        card.setStyleSheet("""
            QFrame {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #d6f0d6, stop:1 #a6d9a6);
                border-radius: 36px;
                border: 2.5px solid #b2e6b2;
                /* 阴影效果 */
                box-shadow: 4px 4px 12px rgba(0, 0, 0, 0.12);
            }
        """)
        card.setGeometry(90, 60, 800, 660)

        layout = QVBoxLayout(card)
        layout.setContentsMargins(60, 50, 60, 50)
        layout.setSpacing(38)

        title = QLabel("AI心理成长关护系统")
        title.setFont(QFont(CARTOON_FONT, 36, QFont.Bold))
        title.setAlignment(Qt.AlignCenter)
        title.setStyleSheet("color: #217a21; background: transparent; letter-spacing: 3px;")
        layout.addWidget(title)
        layout.addSpacing(36)

        user_row = QHBoxLayout()
        user_row.setSpacing(22)
        label_user = QLabel("用户名：")
        label_user.setFont(QFont(CARTOON_FONT, 28, QFont.Bold))
        label_user.setStyleSheet("color:#1c5e1c; background:transparent;")
        self.user_edit = QLineEdit()
        self.user_edit.setFont(QFont(CARTOON_FONT, 26))
        self.user_edit.setPlaceholderText("请输入用户名")
        self.user_edit.setFixedWidth(340)
        self.user_edit.setStyleSheet("""
            QLineEdit {
                padding: 14px 24px;
                border-radius: 24px;
                background-color: #d9f0d9;
                color: #1e6b1e;
                border: 2px solid #8fc88f;
                font-size: 26px;
                transition: background-color 0.3s ease;
            }
            QLineEdit:focus {
                background: #c6e8c6;
                border: 2px solid #5da35d;
            }
        """)
        user_row.addStretch(1)
        user_row.addWidget(label_user)
        user_row.addWidget(self.user_edit)
        user_row.addStretch(1)
        layout.addLayout(user_row)
        layout.addSpacing(24)

        mood_row = QHBoxLayout()
        mood_row.setSpacing(22)
        label_mood = QLabel("当前心情：")
        label_mood.setFont(QFont(CARTOON_FONT, 28, QFont.Bold))
        label_mood.setStyleSheet("color:#1c5e1c; background:transparent;")
        self.mood_combo = QComboBox()
        self.mood_combo.setFont(QFont(CARTOON_FONT, 24, QFont.Bold))
        for mood, emo in EMO_MAP.items():
            self.mood_combo.addItem(f"{emo}  {mood}")
        self.mood_combo.setFixedWidth(210)
        self.mood_combo.setMinimumHeight(46)
        self.mood_combo.setStyleSheet("""
            QComboBox {
                border-radius: 24px;
                background-color: #d9f0d9;
                color: #1e6b1e;
                border: 2px solid #8fc88f;
                padding: 8px 26px 8px 22px;
                selection-background-color: #a1d9a1;
                selection-color: #154715;
                font-size: 24px;
            }
            QComboBox:focus {
                background: #c6e8c6;
                border: 2px solid #5da35d;
            }
            QComboBox QAbstractItemView {
                font-size: 22px;
                color: #1e6b1e;
                background: #e4f2e4;
                selection-background-color: #7ac47a;
                selection-color: #fff;
                border-radius: 0px 0px 16px 16px;
            }
        """)
        mood_row.addStretch(1)
        mood_row.addWidget(label_mood)
        mood_row.addWidget(self.mood_combo)
        mood_row.addStretch(1)
        layout.addLayout(mood_row)

        layout.addSpacing(18)

        self.error_label = QLabel("")
        self.error_label.setFont(QFont(CARTOON_FONT, 22))
        self.error_label.setAlignment(Qt.AlignCenter)
        self.error_label.setStyleSheet("color: #ff7675; padding-top:4px; background: transparent;")
        layout.addWidget(self.error_label, alignment=Qt.AlignHCenter)

        btn_layout = QHBoxLayout()

        self.btn_login = QPushButton("登录")
        self.btn_login.setFont(QFont(CARTOON_FONT, 28, QFont.Bold))
        self.btn_login.setMinimumHeight(56)
        self.btn_login.setStyleSheet("""
            QPushButton {
                background: qlineargradient(x1:0,y1:0,x2:0,y2:1, stop:0 #38d47e, stop:1 #27ab63);
                color: white;
                border-radius: 26px;
                padding: 14px 60px;
                font-size: 28px;
                border: none;
                box-shadow: 0 6px 14px rgba(38, 212, 136, 0.6);
                transition: all 0.3s ease;
            }
            QPushButton:hover {
                background: qlineargradient(x1:0,y1:0,x2:0,y2:1, stop:0 #50e895, stop:1 #39bb6e);
            }
            QPushButton:pressed {
                transform: scale(0.97);
            }
        """)
        self.btn_login.clicked.connect(self.do_login)

        btn_exit = QPushButton("退出")
        btn_exit.setFont(QFont(CARTOON_FONT, 28, QFont.Bold))
        btn_exit.setMinimumHeight(56)
        btn_exit.setStyleSheet("""
            QPushButton {
                background-color: #b2bec3;
                color: white;
                border-radius: 26px;
                padding: 14px 60px;
                font-size: 28px;
                border: none;
                box-shadow: 0 4px 12px rgba(70, 70, 70, 0.3);
                transition: all 0.3s ease;
            }
            QPushButton:hover {
                background-color: #636e72;
            }
            QPushButton:pressed {
                transform: scale(0.97);
            }
        """)
        btn_exit.clicked.connect(self.close_app)

        btn_layout.addStretch()
        btn_layout.addWidget(self.btn_login)
        btn_layout.addSpacing(32)
        btn_layout.addWidget(btn_exit)
        btn_layout.addStretch()
        layout.addLayout(btn_layout)
        layout.addSpacing(10)

        # 等待界面保持原样，或类似风格调整

        self.stacked = QStackedLayout(self)
        self.stacked.addWidget(card)
        self.init_progress = QWidget(self)
        v = QVBoxLayout(self.init_progress)
        v.setAlignment(Qt.AlignCenter)
        self.loading_label = QLabel("正在初始化，请稍候...")
        self.loading_label.setFont(QFont(CARTOON_FONT, 26, QFont.Bold))
        self.loading_label.setAlignment(Qt.AlignCenter)
        v.addWidget(self.loading_label)
        self.progress_bar = QProgressBar()
        self.progress_bar.setMinimum(0)
        self.progress_bar.setMaximum(100)
        self.progress_bar.setValue(0)
        self.progress_bar.setFixedWidth(360)
        self.progress_bar.setStyleSheet("""
            QProgressBar {
                border: 2px solid #158a5a; border-radius: 14px; background: #d9f0d9;
                font-size: 20px;
                height: 36px;
            }
            QProgressBar::chunk {
                background-color: #27ab63;
                border-radius: 12px;
            }
        """)
        v.addWidget(self.progress_bar)
        self.loading_gif = QMovie("loading.gif")
        self.loading_anim = QLabel()
        self.loading_anim.setAlignment(Qt.AlignCenter)
        if self.loading_gif.isValid():
            self.loading_anim.setMovie(self.loading_gif)
            self.loading_gif.start()
        v.addWidget(self.loading_anim)
        self.stacked.addWidget(self.init_progress)
        self.setLayout(self.stacked)

        self.init_worker = None
        self.init_thread = None
        self._init_done = False

    def do_login(self):
        username = self.user_edit.text().strip()
        mood_raw = self.mood_combo.currentText()
        mood = mood_raw.split()[-1]
        if not username:
            self.error_label.setText("请输入用户名！")
            return
        self.username = username
        self.selected_mood = mood
        self.accepted = False
        self.stacked.setCurrentWidget(self.init_progress)
        self.progress_bar.setValue(0)
        self.loading_label.setText("正在初始化系统，请稍候...")
        # 启动初始化线程
        self.init_worker = SystemInitWorker()
        self.init_thread = QThread()
        self.init_worker.moveToThread(self.init_thread)
        self.init_worker.progress.connect(self.set_progress)
        self.init_worker.finished.connect(self.on_init_finished)
        self.init_thread.started.connect(self.init_worker.run)
        self.init_thread.start()
        self.btn_login.setEnabled(False)

    def set_progress(self, value, text):
        self.progress_bar.setValue(value)
        self.loading_label.setText(text)

    def on_init_finished(self):
        self.accepted = True
        self.init_thread.quit()
        self.init_thread.wait()
        self.close()

    def close_app(self):
        self.accepted = False
        self.close()

    def exec_(self):
        self.accepted = False
        self.show()
        loop = QApplication.instance()
        while self.isVisible():
            loop.processEvents()
        return self.accepted

    def get_username(self):
        return self.username

    def get_mood(self):
        return self.selected_mood


class EmotionRecognitionUI(QWidget):
    def __init__(self, username="你", init_mood="平淡"):
        super().__init__()
        self.setWindowTitle("人脸表情识别系统")
        self.setGeometry(100, 100, 1200, 700)
        self.setStyleSheet("background-color: #0b6d3d; color: white;")
        self.emotions = ["angry", "disgust", "fear", "happy", "sad", "surprise", "neutral"]
        self.emoji_map = {
            "angry": "\ud83d\ude20", "disgust": "\ud83e\udde2", "fear": "\ud83d\ude28",
            "happy": "\ud83d\ude04", "sad": "\ud83d\ude22", "surprise": "\ud83d\ude2e", "neutral": "\ud83d\ude10"
        }
        self.cap = None
        self.timer = None
        self.analysis_timer = None
        self.current_frame = None
        self.emotion_history = [self.cn_to_emo(init_mood)]
        self.feedback_engine = None
        self.chat_dialog = None
        self.username = username
        self.initUI()
        self._autostart_done = False

    def initUI(self):
        main_layout = QVBoxLayout()
        main_layout.setSpacing(18)
        main_layout.setContentsMargins(22, 18, 22, 18)

        title = QLabel("人脸表情识别系统")
        title.setFont(QFont(CARTOON_FONT, 30, QFont.Bold))
        title.setAlignment(Qt.AlignCenter)
        title.setStyleSheet("""
            color: white; 
            background-color: #1a8e51; 
            border-radius: 12px; 
            padding: 12px;
            letter-spacing: 1.8px;
            font-weight: 900;
        """)
        main_layout.addWidget(title)

        content_layout = QHBoxLayout()
        content_layout.setSpacing(28)

        image_frame = QFrame()
        image_frame.setStyleSheet("""
            background-color: #06452d;
            border: 3px solid #29c375;
            border-radius: 16px;
        """)
        image_layout = QVBoxLayout(image_frame)
        image_layout.setContentsMargins(14, 14, 14, 14)

        self.image_section = QLabel()
        self.image_section.setMinimumSize(660, 500)
        self.image_section.setStyleSheet("""
            background-color: white;
            padding: 10px;
            border-radius: 12px;
            box-shadow: 0 4px 8px rgba(41, 195, 117, 0.5);
        """)
        self.image_section.setAlignment(Qt.AlignCenter)
        self.image_section.setScaledContents(True)
        image_layout.addWidget(self.image_section)
        content_layout.addWidget(image_frame, 3)

        info_frame = QFrame()
        info_frame.setStyleSheet("""
            background-color: #0b3e22;
            border: 3px solid #29c375;
            border-radius: 16px;
        """)
        info_layout = QVBoxLayout(info_frame)
        info_layout.setContentsMargins(20, 20, 20, 20)
        info_layout.setSpacing(20)

        self.title_label = QLabel("识别结果")
        self.title_label.setFont(QFont(CARTOON_FONT, 22, QFont.Bold))
        self.title_label.setAlignment(Qt.AlignCenter)
        self.title_label.setStyleSheet("color: #29c375; text-shadow: 0 0 4px #1d6d3a;")
        info_layout.addWidget(self.title_label)

        self.emoji = QLabel("\ud83d\ude42")
        self.emoji.setAlignment(Qt.AlignCenter)
        self.emoji.setFont(QFont(CARTOON_FONT, 110))
        self.emoji.setStyleSheet("text-shadow: 0 0 10px #29c375;")
        info_layout.addWidget(self.emoji)

        self.confidence = QLabel("可信度：0.00%")
        self.confidence.setFont(QFont(CARTOON_FONT, 18))
        self.confidence.setAlignment(Qt.AlignCenter)
        self.confidence.setStyleSheet("color: #d4f1c5; font-weight: 700;")
        info_layout.addWidget(self.confidence)

        prob_frame = QFrame()
        prob_frame.setStyleSheet("""
            border: 2px solid #1ccf88;
            border-radius: 12px;
            background-color: #0b6d3d;
        """)
        prob_layout = QVBoxLayout(prob_frame)
        prob_layout.setContentsMargins(14, 14, 14, 14)
        prob_layout.setSpacing(10)

        prob_label = QLabel("各表情概率值")
        prob_label.setFont(QFont(CARTOON_FONT, 14, QFont.Bold))
        prob_label.setStyleSheet("color: #29c375;")
        prob_layout.addWidget(prob_label)

        self.progress_bars = []
        self.prob_labels = []
        for emo in self.emotions:
            hbox = QHBoxLayout()
            hbox.setSpacing(14)

            label = QLabel(self.get_chinese_label(emo))
            label.setFixedWidth(90)
            label.setFont(QFont(CARTOON_FONT, 13, QFont.Bold))
            label.setStyleSheet("color: #a1d9a1;")

            bar = QProgressBar()
            bar.setFixedHeight(22)
            bar.setValue(0)
            bar.setStyleSheet("""
                QProgressBar {
                    border: 2px solid #158a5a;
                    border-radius: 12px;
                    background: white;
                }
                QProgressBar::chunk {
                    background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                        stop:0 #3ee27a, stop:1 #26d488);
                    border-radius: 12px;
                }
            """)

            hbox.addWidget(label)
            hbox.addWidget(bar, 1)
            prob_layout.addLayout(hbox)
            self.progress_bars.append(bar)
            self.prob_labels.append(label)

        info_layout.addWidget(prob_frame)
        info_layout.addStretch(1)
        content_layout.addWidget(info_frame, 1)

        main_layout.addLayout(content_layout)

        btn_frame = QFrame()
        btn_frame.setStyleSheet("""
            border: 2px solid #1ccf88;
            border-radius: 16px;
            background-color: #06452d;
        """)
        btn_layout = QGridLayout(btn_frame)
        btn_layout.setContentsMargins(28, 20, 28, 20)
        btn_layout.setHorizontalSpacing(28)
        btn_layout.setVerticalSpacing(20)

        btn_height = 90

        btn_communicate = QPushButton("AI 实时沟通")
        btn_communicate.setFixedHeight(btn_height)
        btn_communicate.setFont(QFont(CARTOON_FONT, 42, QFont.Bold))
        btn_communicate.setStyleSheet(self.button_style())
        btn_communicate.clicked.connect(self.show_communication_dialog)
        btn_layout.addWidget(btn_communicate, 0, 0, 1, 2)

        btn_pic = QPushButton("图片识别")
        btn_pic.setFixedHeight(btn_height)
        btn_pic.setFont(QFont(CARTOON_FONT, 42, QFont.Bold))
        btn_pic.setStyleSheet(self.button_style())
        btn_pic.clicked.connect(self.load_image)
        btn_layout.addWidget(btn_pic, 1, 0)

        btn_video = QPushButton("视频识别")
        btn_video.setFixedHeight(btn_height)
        btn_video.setFont(QFont(CARTOON_FONT, 42, QFont.Bold))
        btn_video.setStyleSheet(self.button_style())
        btn_layout.addWidget(btn_video, 1, 1)

        btn_cam = QPushButton("实时识别")
        btn_cam.setFixedHeight(btn_height)
        btn_cam.setFont(QFont(CARTOON_FONT, 42, QFont.Bold))
        btn_cam.setStyleSheet(self.button_style())
        btn_cam.clicked.connect(self.toggle_live_recognition)
        btn_layout.addWidget(btn_cam, 2, 0)

        btn_exit = QPushButton("退出系统")
        btn_exit.setFixedHeight(btn_height)
        btn_exit.setFont(QFont(CARTOON_FONT, 42, QFont.Bold))
        btn_exit.setStyleSheet(self.button_style(highlight=True))
        btn_exit.clicked.connect(self.close_app)
        btn_layout.addWidget(btn_exit, 2, 1)

        main_layout.addWidget(btn_frame)
        self.setLayout(main_layout)

    def showEvent(self, event):
        super().showEvent(event)
        # 新增：界面首次显示后自动启动摄像头和实时识别（防止UI卡顿，已在登陆界面初始化完成）
        if not self._autostart_done:
            QTimer.singleShot(300, self.auto_start_camera_and_recognize)
            self._autostart_done = True

    def auto_start_camera_and_recognize(self):
        self.start_camera()
        self.analysis_timer = QTimer()
        self.analysis_timer.timeout.connect(self.snapshot_and_recognize)
        self.analysis_timer.start(1000)
        self.live_mode = True

    def button_style(self, highlight=False):
        if not highlight:
            return """
            QPushButton {
                background-color: #26d488; color: #fff; border-radius: 14px; padding: 12px;
            }
            QPushButton:hover {
                background-color: #37f1a1;
            }
            """
        else:
            return """
            QPushButton {
                background-color: #0b6d3d; color: #fff; border-radius: 14px; padding: 12px; border: 2px solid #26d488;
            }
            QPushButton:hover {
                background-color: #c53939;
                color: #fff;
            }
            """

    def get_chinese_label(self, emo):
        cn_map = {
            "angry": "生气", "disgust": "厌恶", "fear": "害怕",
            "happy": "高兴", "sad": "伤心", "surprise": "惊讶", "neutral": "平淡"
        }
        return cn_map.get(emo, emo)

    def cn_to_emo(self, mood_cn):
        cn_map = {
            "高兴": "happy", "伤心": "sad", "生气": "angry",
            "害怕": "fear", "厌恶": "disgust", "惊讶": "surprise", "平淡": "neutral"
        }
        return cn_map.get(mood_cn, "neutral")

    def load_image(self):
        self.stop_camera_if_needed()
        file_name, _ = QFileDialog.getOpenFileName(self, "选择图片", "", "Images (*.png *.jpg *.jpeg *.bmp)")
        if file_name:
            pixmap = QPixmap(file_name).scaled(self.image_section.size(), Qt.KeepAspectRatio)
            self.image_section.setPixmap(pixmap)
            temp_dir = tempfile.mkdtemp()
            temp_file = os.path.join(temp_dir, "temp_image.jpg")
            shutil.copy(file_name, temp_file)
            self.run_emotion_analysis(temp_file, temp_dir)

    def toggle_live_recognition(self):
        if not self.live_mode:
            self.start_camera()
            self.analysis_timer = QTimer()
            self.analysis_timer.timeout.connect(self.snapshot_and_recognize)
            self.analysis_timer.start(1000)
            self.live_mode = True
        else:
            self.stop_camera_if_needed()
            if self.analysis_timer:
                self.analysis_timer.stop()
                self.analysis_timer = None
            self.live_mode = False

    def start_camera(self):
        if self.cap is not None:
            return
        self.cap = cv2.VideoCapture(0)
        if not self.cap.isOpened():
            self.show_error("无法打开摄像头")
            self.cap = None
            return
        self.timer = QTimer()
        self.timer.timeout.connect(self.display_camera_frame)
        self.timer.start(30)

    def stop_camera_if_needed(self):
        if self.timer:
            self.timer.stop()
            self.timer = None
        if self.cap:
            self.cap.release()
            self.cap = None

    def display_camera_frame(self):
        if self.cap is not None:
            ret, frame = self.cap.read()
            if ret:
                rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                disp_frame = cv2.resize(rgb_frame, (700, 500))
                qt_img = QImage(disp_frame.data, disp_frame.shape[1], disp_frame.shape[0], disp_frame.strides[0], QImage.Format_RGB888)
                pixmap = QPixmap.fromImage(qt_img)
                self.image_section.setPixmap(pixmap)
                self.current_frame = frame.copy()

    def run_emotion_analysis(self, temp_file, temp_dir):
        self.recognize_thread = DeepFaceThread(temp_file)
        self.recognize_thread.result_signal.connect(self.update_emotion_display)
        self.recognize_thread.error_signal.connect(self.show_error)
        self.recognize_thread.finished.connect(lambda: shutil.rmtree(temp_dir))
        self.title_label.setText("识别中，请稍候...")
        self.emoji.setText("\u23f3")
        self.confidence.setText("正在分析...")
        for bar in self.progress_bars:
            bar.setValue(0)
        self.recognize_thread.start()

    def snapshot_and_recognize(self):
        if self.current_frame is None:
            self.show_error("未获取到摄像头画面")
            return
        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, "temp_snapshot.jpg")
        cv2.imwrite(temp_file, self.current_frame)
        self.run_emotion_analysis(temp_file, temp_dir)

    def update_emotion_display(self, probs, dominant_emotion):
        self.title_label.setText(f"{dominant_emotion.capitalize()}--{self.get_chinese_label(dominant_emotion)}")
        self.emoji.setText(self.emoji_map.get(dominant_emotion, "\ud83d\ude42"))
        val = probs[dominant_emotion]
        self.confidence.setText(f"可信度：{val:.2f}%")
        for i, emo in enumerate(self.emotions):
            v = int(min(max(probs.get(emo, 0), 0), 100))
            self.progress_bars[i].setValue(v)
        self.emotion_history.append(dominant_emotion)
        if len(self.emotion_history) > 10:
            self.emotion_history.pop(0)
        if self.chat_dialog and self.chat_dialog.isVisible():
            self.chat_dialog.update_emotion_trend(self.emotion_history)

    def show_error(self, message):
        self.title_label.setText("错误")
        self.emoji.setText("\u274c")
        self.confidence.setText(message)
        for bar in self.progress_bars:
            bar.setValue(0)

    def close_app(self):
        # 1. 立即关闭所有主UI窗口
        for w in QApplication.topLevelWidgets():
            if w is not self:
                try:
                    w.close()
                except Exception:
                    pass
        self.hide()  # 立即隐藏主界面

        # 2. 弹出PDF生成进度弹窗
        progress_dialog = PDFProgressDialog()
        progress_dialog.setModal(True)
        progress_dialog.show()
        QApplication.processEvents()

        # 3. 启动PDF生成线程
        from psychological_report_pdf import PsychologicalPDFReport

        initial_emotion = getattr(self, "session_initial_emotion",
                                  self.get_chinese_label(self.emotion_history[0]) if self.emotion_history else "None")
        final_emotion = self.get_chinese_label(self.emotion_history[-1]) if self.emotion_history else "None"
        negative_emos = ["伤心", "生气", "厌恶", "害怕"]
        neg_count = sum(1 for emo in self.emotion_history if self.get_chinese_label(emo) in negative_emos)
        total = len(self.emotion_history)
        suicide_score = int((neg_count / total) * 80 + 10) if total > 0 else 0
        depression_score = int((neg_count / total) * 80 + 10) if total > 0 else 0
        chat_hist = getattr(self, "session_chat_history", [])

        pdf_generator = PsychologicalPDFReport(client=client)
        kwargs = dict(
            username=getattr(self, "username", "Testee"),
            initial_emotion=initial_emotion,
            final_emotion=final_emotion,
            chat_history=chat_hist,
            suicide_score=suicide_score,
            depression_score=depression_score
        )

        def on_finished(pdf_path, success):
            progress_dialog.progress.setValue(100)
            if success:
                progress_dialog.label.setText("PDF报告生成完成！")
                QApplication.processEvents()
                time.sleep(0.4)
            else:
                progress_dialog.label.setText(f"生成失败：{pdf_path}")
                QApplication.processEvents()
                time.sleep(1.1)
            progress_dialog.close()
            QApplication.quit()

        def on_progress(val):
            progress_dialog.progress.setValue(val)
            QApplication.processEvents()

        thread = PDFGeneratorThread(pdf_generator, kwargs)
        thread.progress_signal.connect(on_progress)
        thread.finished_signal.connect(on_finished)
        thread.start()
        progress_dialog.exec_()

    def closeEvent(self, event):
        self.stop_camera_if_needed()
        try:
            self.generate_psychological_pdf_report()
        except Exception as e:
            print("生成心理报告出错：", e)
        event.accept()

    def show_communication_dialog(self):
        from ai_chat_dialog import AIChatDialog, SimpleSelfLearningEngine
        if self.feedback_engine is None:
            self.feedback_engine = SimpleSelfLearningEngine()
        if self.chat_dialog and self.chat_dialog.isVisible():
            self.chat_dialog.raise_()
            return
        self.chat_dialog = AIChatDialog(self.emotion_history, self.feedback_engine, self,client)
        self.chat_dialog.setWindowModality(Qt.ApplicationModal)
        self.chat_dialog.show()

    def generate_psychological_pdf_report(self):
        from psychological_report_pdf import PsychologicalPDFReport
        import datetime

        initial_emotion = getattr(self, "session_initial_emotion",
                                  self.get_chinese_label(self.emotion_history[0]) if self.emotion_history else "None")
        final_emotion = self.get_chinese_label(self.emotion_history[-1]) if self.emotion_history else "None"

        negative_emos = ["伤心", "生气", "厌恶", "害怕"]
        neg_count = sum(1 for emo in self.emotion_history if self.get_chinese_label(emo) in negative_emos)
        total = len(self.emotion_history)
        suicide_score = int((neg_count / total) * 80 + 10) if total > 0 else 0
        depression_score = int((neg_count / total) * 80 + 10) if total > 0 else 0

        chat_hist = getattr(self, "session_chat_history", [])

        pdf_generator = PsychologicalPDFReport()
        pdf_path = pdf_generator.gen_report(
            username=getattr(self, "username", "Testee"),
            initial_emotion=initial_emotion,
            final_emotion=final_emotion,
            chat_history=chat_hist,
            suicide_score=suicide_score,
            depression_score=depression_score
        )
        print(f"心理评估报告已生成：{pdf_path}")


if __name__ == "__main__":
    client = QwenCompatibleClient.with_openai_api()
    app = QApplication(sys.argv)
    login_dialog = LoginDialog()
    login_result = login_dialog.exec_()
    if not login_result:
        sys.exit(0)
    username = login_dialog.get_username()
    mood = login_dialog.get_mood()
    window = EmotionRecognitionUI(username=username, init_mood=mood)
    window.show()
    sys.exit(app.exec_())